package com.hm.plugin.httpclient.util;

import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.hm.plugin.httpclient.def.HttpClientDef;
import com.hm.plugin.httpclient.def.HttpClientDef.Setting.Response;
import com.hm.plugin.httpclient.def.HttpMethods;
import com.hm.plugin.httpclient.model.ResponseCallBack;

/**
 * @author shishun.wang
 * @date 下午5:06:06 2016年6月22日
 * @version 1.0
 * @describe
 */
@SuppressWarnings("unchecked")
@Component
public class MyHttpClient extends HttpClientBuilder{

	private static Logger logger = LoggerFactory.getLogger(MyHttpClient.class);
	
	public <T> ResponseCallBack<T> upload(String uri,String path) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.POST).uri(uri).upload(path));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}
	
	public <T> ResponseCallBack<T> put(String uri,T model) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.PUT).uri(uri).json(model));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}
	
	public <T> ResponseCallBack<T> delete(String uri,Map<String, Object> param) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.DELETE).uri(uri).map(param));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}
	
	public <T> ResponseCallBack<T> post(String uri,Map<String, Object> param) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.POST).uri(uri).map(param));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}
	
	public <T> ResponseCallBack<T> post(String uri) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.POST).uri(uri));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}

	public <T> ResponseCallBack<T> post(String uri,T model) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.POST).uri(uri).json(model));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}
	
	public <T> ResponseCallBack<T> get(String uri) throws Exception {
		HttpResponse response = execute(new MyHttpConfig().method(HttpMethods.GET).uri(uri));
		return (ResponseCallBack<T>) JSON.parseObject(text4json(response), ResponseCallBack.class);
	}

	public String text4json(HttpResponse response) throws Exception {
		HttpEntity entity = response.getEntity();
		if (null != entity) {
			String json = EntityUtils.toString(entity, Response.CHART);
			if (response.getStatusLine().getStatusCode() == HttpClientDef.Setting.Response.OK) {
				return json;
			}
			logger.warn("request fail " + json);
			return json;
		}
		return null;
	}

	public HttpResponse execute(MyHttpConfig httpConfig) {
		HttpClient httpClient = this.build();
		try {
			HttpRequestBase request = loadRequest(httpConfig.getUri(), httpConfig.getHttpMethod());
//			request.setHeader("Client-AuthorizationToken", "57773d280cf202b6bf03a9aa");
//			request.setHeader("YQJ_APP_USER_SESSION_ID", "Aq4VS8Ecwak2dRB6Kr8kQ8TELoXC7j3FnWNc6eQRC0NrGNC6IKOz48kZirot4zvz");
			request.setHeader("YQJ_APP_USER_ROLE", "PARENT");
			// 判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
			if (HttpEntityEnclosingRequestBase.class.isAssignableFrom(request.getClass())) {
				 ((HttpEntityEnclosingRequestBase)request).setEntity(httpConfig.getHttpEntity());
			}
			return httpClient.execute(request);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private HttpRequestBase loadRequest(String uri, HttpMethods methods) {
		HttpRequestBase httpRequestBase = null;
		switch (methods) {
		case GET:
			httpRequestBase = new HttpGet(uri);
			break;
		case POST:
			httpRequestBase = new HttpPost(uri);
			break;
		case PUT:
			httpRequestBase = new HttpPut(uri);
			break;
		case DELETE:
			httpRequestBase = new HttpDelete(uri);
		case PATCH:
			httpRequestBase = new HttpPatch(uri);
			break;
		case OPTIONS:
			httpRequestBase = new HttpOptions(uri);
			break;
		default:
			break;
		}
		return httpRequestBase;
	}
}
